/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.IAccelerometer3D;
import com.sun.spot.sensorboard.peripheral.ISwitch;
import com.sun.spot.sensorboard.peripheral.ISwitchListener;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.util.IEEEAddress;
import com.sun.squawk.util.StringTokenizer;
import java.io.IOException;
import java.util.Random;


/**
 *
 * @author Dustin
 */
class Game implements ISwitchListener, Protocoll{
    private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
    private ISwitch leftSwitch = EDemoBoard.getInstance().getSwitches()[0];
    private ISwitch rightSwitch = EDemoBoard.getInstance().getSwitches()[1];
    private IAccelerometer3D accelerometer = EDemoBoard.getInstance().getAccelerometer();
    private boolean hasPotato;
    private long endTime;
    private Main main;
    private int score = 0;
    private boolean isOut;
    private boolean gameStarted = false;

    /**
     * Constructor 
     * @param aMain
     */
    public Game(Main aMain) {
        main = aMain;
        leds[3].setRGB(0, 0, 255);
        leds[4].setRGB(0, 0, 255);
                
        leds[0].setOn();
        leds[7].setOn();

        leftSwitch.addISwitchListener(this);
        rightSwitch.addISwitchListener(this);

        if(main.getConnections().isEmpty()){
            leds[0].setRGB(255, 0, 0);
            leds[7].setRGB(255, 0, 0);
        }
        
        startGameThread();
        System.out.println("Game thread started");
    }


   /**
    * Thread that checks if endtime has been reached and looks at the accelormeter
    */
   public void startGameThread() {
        new Thread(){
            public void run() {
                while(true){
                    if(hasPotato){
                        if(gameStarted){
                       //check if the endtime of the potato has been reached
                            if(!isEndTime()){
                               isOut();
                            }
                        }

                        //keep looking at the accelormeter
                        try {
                            double accelX = accelerometer.getAccelX();
                                if(accelX > 2) { //versnelling groter dan 2
                                    System.out.println("pass @ speed " + accelX);

                                    //nieuwe random maken, random een entry van de lijst met connecties pakken
                                    Random r = new Random();
                                    Connection con = (Connection) main.getConnections().elementAt((int)(r.nextDouble() * main.getConnections().size()));
                                    long adress = IEEEAddress.toLong(con.getAdress());

                                    //potato sturen naar het adres van de hierboven gevonden random connectie
                                    main.sendConnectionMessage(endTime + " ", adress);
                                    hasPotato = false;
                                    display();
//                                        try {
//                                            Thread.sleep(500);
//                                        } catch (InterruptedException ex) {
//                                            ex.printStackTrace();
//                                        }
                                } else if (accelX < -2) { //versnelling kleiner dan 2
                                    System.out.println("pass @ speed " + accelX);

                                    //nieuwe random maken, random een entry van de lijst met connecties pakken
                                    Random r = new Random();
                                    Connection con = (Connection) main.getConnections().elementAt((int)(r.nextDouble() * main.getConnections().size()));
                                    long adress = IEEEAddress.toLong(con.getAdress());

                                    //potato sturen naar het adres van de hierboven gevonden random connectie
                                    main.sendConnectionMessage(endTime + " ", adress);
                                    hasPotato = false;
                                    display();
//                                    try {
//                                        Thread.sleep(500);
//                                    } catch (InterruptedException ex) {
//                                        ex.printStackTrace();
//                                    }
                                }

                            } catch (IOException ex) {
                                System.err.println("Error @ Game.java:startAccelerometerThread() - IOException!");
                            }

                    }
                }
            };
        }.start();
    }

    /**
     * check if endtime is reached
     * @return
     */
    public boolean isEndTime() {
        //System.out.println(endTime);
       // System.out.println(System.currentTimeMillis());
        return endTime >= System.currentTimeMillis();
    }

    /**
     * sends a message to another spot by adress
     * @param address
     */
    public void sendMessage(long address) {
        if(isEndTime()) { //if endtime not reached send a potato and set haspotato to false
            main.sendConnectionMessage(endTime + "", address);
            hasPotato = false;
            display();
        } else {
            main.sendConnectionMessage(endTime + "", address);
        }
    }

    /**
     * handles recieving of messages
     * @param message
     */
    public void receiveMessage(String message) {
        String[] parts = separateStrings(message);
        System.out.println("-- message recieved: " + message);
        if(parts[0].length() > 10){ //if a message is bigger dan 10 it's a potato, potatos can only be recieved when the game has started
            if(gameStarted){
                endTime = Long.parseLong(parts[0]);
                hasPotato = true;
                display();
            } else {
                System.out.println(message + " recieved while game was not started");
            }
        } else {
            if(Integer.parseInt(parts[0]) == STARTGAME){
                gameStarted();
            
            }
            if(Integer.parseInt(parts[0]) == DEADPLAYER){
                resetForRound();
            }
        }
       
    }

    /**
     * sets the score one up
     */
    public void upScore(){
        score++;
    }

    /**
     * returns the score
     * @return score
     */
    public int getScore(){
        return score;
    }

    /**
     * sets the endTime
     * @param anEndTime
     */
    public void setEndTime(long anEndTime) {
        endTime = anEndTime;
    }

    /**
     * handles the fact when you lose a round
     */
    public void isOut(){
        isOut = true;
        System.out.println("i'm out");
        main.massMessage(DEADPLAYER + "");
        hasPotato = false;
        
        gameStarted = false;

        display();
             
            for (int i = 1; i < 7; i++) {
                leds[i].setRGB(255,0,0);
                leds[i].setOn();
            }
        
         leds[0].setRGB(255,0,0);
         leds[7].setRGB(255,0,0);
         leds[0].setOn();
         leds[7].setOn();

//         main.idleAllConnections(); // should move all connections to idle and start waiting again for new connections
        
    }

    /**
     * generates an endtime
     * @return the timestamp from current time + time for a potato to end
     */
    public long generateEndTime(){
        Random r = new Random();
        long current = System.currentTimeMillis(); // get the current time
        
        long eerste = Long.parseLong(Long.toString(current).substring(0,5)); // split the long, because the entire long is too big for an int
        long tweede = Long.parseLong(Long.toString(current).substring(4));
        System.out.println(current);
        System.out.println(eerste);
        System.out.println(tweede);

        int next = 0;
        
        //random between 30 en 90 bepalen
        while(next < 30){
             next = r.nextInt(90);
        }
        
        next = next * 1000; //x 1000 to make seconds

        //ff om te testen 10 seconden
        next = 10 * 1000;
        return Long.parseLong("" + eerste + (Integer.parseInt(Long.toString(tweede)) + next)); // add time to the current time
        
    }

    /**
     * display to control the leds
     */
    public void display() {
        for(int i = 1; i < 7; i++){
            leds[i].setOff();
        }
        if(gameStarted){ //if the game is started and running the outside leds will be green
            leds[0].setRGB(0,255,0);
            leds[7].setRGB(0,255,0);
            leds[1].setOn();
            leds[7].setOn();
        }
        if(hasPotato) { // potato will be visible with 2 blue leds in the middle
            leds[3].setRGB(0,0,255);
            leds[4].setRGB(0,0,255);
            leds[3].setOn();
            leds[4].setOn();
        } else { // if the potato is gone, the leds will go off
            leds[3].setOff();
            leds[4].setOff();
        }
    }

    /**
     * to seperate the strings from an incoming message
     * @param msg
     * @return
     */
   private String[] separateStrings(String msg) {
        StringTokenizer stk = new StringTokenizer(msg, " ");
        String [] result = new String[stk.countTokens()];
        for (int i = 0; stk.hasMoreTokens(); i++) {
            result[i] = stk.nextToken();
            }
        return result;
    }

   /**
    * prepares the spot so a game can be started
    * @require more than 1 other spot connected
    */
    public void prepareForGame(){
        leftSwitch.addISwitchListener(this); //add listeners so a game can be started by button
        rightSwitch.addISwitchListener(this);

         leds[0].setRGB(0, 0, 255); // outside leds will be Blue when waiting for a game
         leds[7].setRGB(0, 0, 255);
    }

    /**
     * begins a game, this Spot has started
     */
    public void beginGame(){
        
        endTime = generateEndTime(); //set endTime
        
        hasPotato = true; //this spot will have the potato since this spot started the game
        
        main.massMessage(STARTGAME +" "); //let other spots know the game has started

        gameStarted = true;

        leftSwitch.removeISwitchListener(this); //remove listeners once game is started
        rightSwitch.removeISwitchListener(this);

        leds[0].setRGB(0, 0, 255);
        leds[7].setRGB(0, 0, 255);
        display();
        System.out.println("begin game started");
    }

    /**
     * If another Spot has started the game, this sets this spot to the right status
     */
    public void gameStarted(){
        leftSwitch.removeISwitchListener(this); // remove listeners once game is started
        rightSwitch.removeISwitchListener(this);

        display();

        leds[0].setRGB(0, 255, 0); //Set leds to green to see that the game has started
        leds[7].setRGB(0, 255, 0);

        gameStarted = true;
        
        System.out.println("game started");
    }

    /**
     * Listener for switch pressed
     * @param sw
     */
    public void switchPressed(ISwitch sw) {
        int switchNum = (sw == leftSwitch) ? 1 : 2;

        if(switchNum == 1){
            beginGame();
        }
        else if( switchNum == 2){
            System.out.println("Broadcasting uit!");
            main.setBroadcasting(false);
            leds[6].setRGB(255, 0, 0);
            display();
        }
        System.out.println("Switch " + switchNum + " closed.");
        

    }

    /**
     * Listener for switch released
     * @param sw
     */
    public void switchReleased(ISwitch sw) {
        int switchNum = (sw == leftSwitch) ? 1 : 2;
        System.out.println("Switch " + switchNum + " opened.");
    }

    /**
     * When a round is run and a spot is out this function will prepare for the next round
     */
    public void resetForRound(){
        if(main.getConnections().isEmpty()){ // if you're the only spot left you're obviously the winner of the game
            for (int i = 1; i < 7; i++) {
                leds[i].setRGB(255,255,255);
                leds[i].setOn();
            }
            System.out.println("i'm the winner!");

            upScore(); // up your score because you have won

            
        } else {
            System.out.println("preparing for next round");

            leftSwitch.addISwitchListener(this); //add the switches again so you can press to begin a new round
            rightSwitch.addISwitchListener(this);

            leds[0].setRGB(0, 255, 0); //set leds so you can see a round has ended and you can start a new one
            leds[1].setRGB(0, 0, 255);
            leds[2].setRGB(0, 0, 255);
            leds[5].setRGB(0, 0, 255);
            leds[6].setRGB(0, 0, 255);
            leds[7].setRGB(0, 255, 0);
            leds[1].setOn();
            leds[2].setOn();
            leds[5].setOn();
            leds[6].setOn();
        }
        
    }

    public void setConnectLed(){
        int i = main.getConnections().size();
        for(int j = i; i < 8; i++){
            leds[j].setRGB(0,255,0);
            leds[j].setOn();

        }
    }

}
